#include "HttpRequest.h"
#include <iostream>
#include <algorithm>
#include <sstream>
#include <ctime>

using std::cout;
using std::endl;

HttpRequest::HttpRequest()
: _method(HttpMethod::UNKNOWN)
, _isComplete(false)
, _contentLength(0)
{
}

HttpRequest::~HttpRequest()
{
}

bool HttpRequest::parseRequest(const string &rawRequest)
{
    reset();
    
    if (rawRequest.empty()) {
        return false;
    }
    
    // 查找请求头和请求体的分割点（\r\n\r\n）
    size_t headerEndPos = rawRequest.find("\r\n\r\n");
    if (headerEndPos == string::npos) {
        // 可能还没收到完整的请求头
        return false;
    }
    
    string headerPart = rawRequest.substr(0, headerEndPos);
    string bodyPart = rawRequest.substr(headerEndPos + 4);
    
    // 解析请求头部分
    std::istringstream headerStream(headerPart);
    string line;
    bool isFirstLine = true;
    
    while (std::getline(headerStream, line)) {
        // 移除行尾的\r
        if (!line.empty() && line.back() == '\r') {
            line.pop_back();
        }
        
        if (isFirstLine) {
            if (!parseRequestLine(line)) {
                return false;
            }
            isFirstLine = false;
        } else {
            // 解析请求头
            size_t colonPos = line.find(':');
            if (colonPos != string::npos) {
                string name = line.substr(0, colonPos);
                string value = line.substr(colonPos + 1);
                
                // 去除空格
                name.erase(0, name.find_first_not_of(" \t"));
                name.erase(name.find_last_not_of(" \t") + 1);
                value.erase(0, value.find_first_not_of(" \t"));
                value.erase(value.find_last_not_of(" \t") + 1);
                
                // 转换为小写进行存储
                std::transform(name.begin(), name.end(), name.begin(), ::tolower);
                _headers[name] = value;
            }
        }
    }
    
    // 获取Content-Length
    auto contentLengthIter = _headers.find("content-length");
    if (contentLengthIter != _headers.end()) {
        _contentLength = std::stoul(contentLengthIter->second);
    }
    
    // 检查请求体是否完整
    if (_contentLength > 0) {
        if (bodyPart.size() >= _contentLength) {
            _body = bodyPart.substr(0, _contentLength);
            _isComplete = true;
        } else {
            // 请求体未完整接收
            return false;
        }
    } else {
        _body = bodyPart;
        _isComplete = true;
    }
    
    return true;
}

bool HttpRequest::parseRequestLine(const string &line)
{
    std::istringstream iss(line);
    string methodStr, path, version;
    
    if (!(iss >> methodStr >> path >> version)) {
        return false;
    }
    
    _method = stringToMethod(methodStr);
    _version = version;
    
    // 解析路径和查询参数
    size_t queryPos = path.find('?');
    if (queryPos != string::npos) {
        _path = path.substr(0, queryPos);
        string queryString = path.substr(queryPos + 1);
        parseQueryString(queryString);
    } else {
        _path = path;
    }
    
    return true;
}

void HttpRequest::parseQueryString(const string &queryString)
{
    std::istringstream queryStream(queryString);
    string pair;
    
    while (std::getline(queryStream, pair, '&')) {
        size_t equalPos = pair.find('=');
        if (equalPos != string::npos) {
            string name = pair.substr(0, equalPos);
            string value = pair.substr(equalPos + 1);
            _queries[name] = value;
        } else {
            _queries[pair] = "";
        }
    }
}

HttpMethod HttpRequest::stringToMethod(const string &methodStr)
{
    if (methodStr == "GET") return HttpMethod::GET;
    if (methodStr == "POST") return HttpMethod::POST;
    if (methodStr == "PUT") return HttpMethod::PUT;
    if (methodStr == "DELETE") return HttpMethod::DELETE;
    if (methodStr == "HEAD") return HttpMethod::HEAD;
    if (methodStr == "OPTIONS") return HttpMethod::OPTIONS;
    return HttpMethod::UNKNOWN;
}

string HttpRequest::getHeader(const string &name) const
{
    string lowerName = name;
    std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(), ::tolower);
    
    auto it = _headers.find(lowerName);
    if (it != _headers.end()) {
        return it->second;
    }
    return "";
}

bool HttpRequest::hasHeader(const string &name) const
{
    string lowerName = name;
    std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(), ::tolower);
    return _headers.find(lowerName) != _headers.end();
}

string HttpRequest::getQuery(const string &name) const
{
    auto it = _queries.find(name);
    if (it != _queries.end()) {
        return it->second;
    }
    return "";
}

bool HttpRequest::hasQuery(const string &name) const
{
    return _queries.find(name) != _queries.end();
}

string HttpRequest::getMethodString() const
{
    switch (_method) {
        case HttpMethod::GET: return "GET";
        case HttpMethod::POST: return "POST";
        case HttpMethod::PUT: return "PUT";
        case HttpMethod::DELETE: return "DELETE";
        case HttpMethod::HEAD: return "HEAD";
        case HttpMethod::OPTIONS: return "OPTIONS";
        default: return "UNKNOWN";
    }
}

void HttpRequest::reset()
{
    _method = HttpMethod::UNKNOWN;
    _path.clear();
    _version.clear();
    _body.clear();
    _headers.clear();
    _queries.clear();
    _isComplete = false;
    _contentLength = 0;
}

string HttpRequest::toString() const
{
    std::ostringstream oss;
    oss << "HTTP Request:\n";
    oss << "  Method: " << getMethodString() << "\n";
    oss << "  Path: " << _path << "\n";
    oss << "  Version: " << _version << "\n";
    oss << "  Headers:\n";
    for (const auto &header : _headers) {
        oss << "    " << header.first << ": " << header.second << "\n";
    }
    if (!_queries.empty()) {
        oss << "  Query Parameters:\n";
        for (const auto &query : _queries) {
            oss << "    " << query.first << "=" << query.second << "\n";
        }
    }
    if (!_body.empty()) {
        oss << "  Body: " << _body << "\n";
    }
    return oss.str();
}